package com.vimi8.app.framework.net

import android.content.Context
import com.google.gson.Gson
import io.oschina.binv.kapp.framework.utils.Logger
import io.oschina.binv.kapp.framework.extend.printOrReport
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import retrofit2.Response
import kotlin.properties.Delegates

/**
 * Created by xuybin on 2017/8/15.
 */
abstract class BaseObserver<T> (val context: Context): Observer<Response<T>> {
    val Log= Logger(context::class.java.canonicalName)
    override fun onNext(t: Response<T>) {
        var httpError :HttpError by Delegates.notNull()
        //如拦截器处已经处理并抛出异常,则此处为恒为真
        if (t.isSuccessful) {
            val data = t.body()
            if (data != null && data.isNotInitialValue()) {
                try {
                    onSuccess(data)
                } catch (ex: Exception) {
                    context.printOrReport(ex)
//                    Log.e(ex.message)
//                    MobclickAgent.reportError(context, "onSuccess(${data.toString()})    ->ex:${ex.message}")
                }finally {
                    //正常结束
                    return
                }
            } else{
                //请求成功,返回不为空 且 有至少一个数据填充
                httpError = HttpError(t.code(), "无效数据", "返回数据为空或无效!", "", t.raw().request().url().toString(), t.raw().request().method())
            }
        }else{
            //请求错误
            httpError =HttpError.newInstance(t.code(),t.raw().request(),t.errorBody())
        }
        try {
            onError(httpError)
            context.printOrReport(Throwable("onError(${httpError.toString()})"))
            //MobclickAgent.reportError(context, "onError(${httpError.toString()})")
        } catch (ex: Exception) {
//            MobclickAgent.reportError(context, "onError(${httpError.toString()})    ->ex:${ex.message}")
//            Log.e(ex.message)
            context.printOrReport(ex)
        }
    }

    //网络异常
    override fun onError(e: Throwable) {
        var httpError: HttpError by Delegates.notNull()
        when (e) {
            is HttpError -> {
                httpError = e
            }
            else -> {
                httpError=HttpError.newInstance(e)
            }
        }
        try {
            onError(httpError)
            //MobclickAgent.reportError(context, "onError(${httpError.toString()})")
            context.printOrReport(Throwable("onError(${httpError.toString()})"))
        } catch (ex: Exception) {
            context.printOrReport(ex)
//            MobclickAgent.reportError(context, "onError(${httpError.toString()})    ->ex:${ex.message}")
//            Log.e(TAG,ex.message)
        }
    }

    override fun onSubscribe(d: Disposable) {
        Log.i("onSubscribe")
    }

    override fun onComplete() {
        Log.i("onComplete")
    }


    open fun onError(httpError: HttpError) {
        //Log.i("onError")
        context.printOrReport(Throwable("onError(${httpError.toString()})"))
    }

    abstract fun onSuccess(data: T)
    //检查当前对象是否是类的初值
    private fun Any.isNotInitialValue(): Boolean {
        val gson=Gson();
        var initialValue = this
        try {
            initialValue = gson.fromJson("{}", this.javaClass)
        } catch (ex1: Exception) {
            try {
                initialValue = this.javaClass.newInstance()
            } catch (ex2: Exception) {
                context.printOrReport(ex2)
                //Log.e("${this.javaClass.canonicalName}.isNotInitialValue ex1->${ex1.message},ex2->${ex2.message}")
            }
        }
        try {
            if (this != initialValue){
                return true//data class 可以直接比较
            }else if(gson.toJson(this) != gson.toJson(initialValue)){
                 return true//非 data class 序列化后比较
            }else{
                return false
            }
        }  catch (ex3: Exception) {
            context.printOrReport(ex3)
            //Log.e("${this.javaClass.canonicalName}.isNotInitialValue ex3->${ex3.message}")
            return false
        }
    }
}



